<template>
  <div class="menu-container">
    <!-- 菜单树 -->
    <el-card class="tree-card">
      <template #header>
        <el-button @click="handleCreateRootMenu">新增顶级菜单</el-button>
      </template>
      <div class="menu-tree">
        <!-- 点击节点后不展开 -->
        <el-tree
          ref="menuTreeRef"
          highlight-current
          node-key="id"
          :data="menus"
          :expand-on-click-node="false"
          :props="defaultProps"
          draggable
          :allow-drop="allowDrop"
          :allow-drag="allowDrag"
          @node-click="handleNodeClick"
          @node-drop="handleNodeDrop"
        >
          <template #default="{ node, data }">
            <span class="custom-tree-node">
              <span>{{ node.label }}</span>
              <span>
                <el-button link @click.stop="handleCreateChildMenu(data)"
                  >添加</el-button
                >
                <el-button link @click.stop="handleRemoveMenu(data)"
                  >删除</el-button
                >
              </span>
            </span>
          </template>
        </el-tree>
      </div>
    </el-card>
  </div>
  <el-card class="edit-card">
    <template #header> 编辑菜单 </template>
    <editor-menu
      v-show="editData && editData.id"
      :data="editData!"
      @updateEdit="handleUpdateEdit"
    />
    <span v-if="editData == null">从菜单列表选择一项后，进行编辑</span>
  </el-card>
  <right-panel v-model="panelVisible" :title="panelTitle">
    <add-menu ref="addMenuInstance" @submit="submitMenuForm"></add-menu>
  </right-panel>
</template>

<script setup lang="ts">
import { MenuData } from "@/api/menu"
import { useReloadPage } from "@/hooks/useReload"
import { useMenuStore } from "@/stores/menu"
import { ITreeItemData } from "@/utils/generateTree"
import type Node from "element-plus/es/components/tree/src/model/node"

const store = useMenuStore()
const { reloadPage } = useReloadPage()
const menus = computed(() => store.state.menuTreeData)
const menuType = ref(0) // 0顶级 1子级
const panelTitle = computed(() =>
  menuType.value === 0 ? "添加顶级菜单" : "添加子菜单"
)
const panelVisible = ref(false)
const defaultProps = ref({
  children: "children",
  label: "title"
})

onMounted(() => {
  store.getAllMenuList()
})

const handleCreateRootMenu = () => {
  menuType.value = 0
  panelVisible.value = true
}
const parentData = ref<ITreeItemData | null>(null)
const handleCreateChildMenu = (data: ITreeItemData) => {
  menuType.value = 1
  panelVisible.value = true
  parentData.value = data
}
const resetStatus = () => {
  panelVisible.value = false
  parentData.value = null
}

const submitMenuForm = async (data: ITreeItemData) => {
  if (menuType.value === 0) {
    await handleAddRootMenu({ ...data })
  } else {
    await handleAddChildMenu({ ...data })
  }
  resetStatus()
}

const getMenuNodeSortId = (list: ITreeItemData[]) => {
  if (list && list.length) {
    return list[list.length - 1].sort_id + 1
  }
  return 0
}
const allocRootMenuId = (data: ITreeItemData) => {
  const sortId = getMenuNodeSortId(menus.value)
  data.sort_id = sortId
  data.parent_id = "0"
}
const { proxy } = getCurrentInstance()!
const handleAddRootMenu = async (data: ITreeItemData) => {
  allocRootMenuId(data)
  const result = await store.appendMenu(data)
  if (result) {
    proxy?.$message.success("菜单创建成功")
  }
  reloadPage()
}
const allocChildMenuId = (data: ITreeItemData, parentData: ITreeItemData) => {
  const pid = parentData.id as number
  let sortId = 0
  if (!parentData.children) {
    parentData.children = []
  }
  if (parentData.children.length) {
    sortId = getMenuNodeSortId(parentData.children)
  }
  data.sort_id = sortId
  data.parent_id = pid.toString()
  return data
}
const handleAddChildMenu = async (data: ITreeItemData) => {
  const child = allocChildMenuId(data, parentData.value!)
  let result = await store.appendMenu(child)
  if (result) {
    proxy?.$message.success("菜单创建成功")
  }
  reloadPage()
}
const handleRemoveMenu = async (menuData: ITreeItemData) => {
  try {
    proxy?.$confirm(`您确认要删除菜单${menuData.title}吗？`, "删除确认", {
      type: "warning"
    })
    await store.removeMenu(menuData)
    reloadPage()
  } catch {
    proxy?.$message({
      type: "info",
      message: "已取消删除"
    })
  }
}
const editData = ref<MenuData>()
const handleNodeClick = (data: MenuData) => {
  editData.value = { ...data }
}
const handleUpdateEdit = async (data: Partial<MenuData>) => {
  const result = await store.updateMenu(data)
  if (result) {
    proxy?.$message.success("菜单编辑成功")
    reloadPage()
  }
}

type DropType = "before" | "after" | "inner"
const allowDrop = (draggingNode: Node, dropNode: Node, type: DropType) => {
  if (dropNode.data.parent_id === 0 || dropNode.data.parent_id === null) {
    return type !== "inner"
  }
}

const allowDrag = (draggingNode: Node) => {
  const data = draggingNode.data
  return data.parent_id === 0 || data.parent_id === null
}

const handleNodeDrop = () => {
  store.updateBulkMenu()
}
</script>

<style lang="scss">
.menu-container {
  @apply flex p-20px;
}
.menu-tree {
  @apply h-400px overflow-y-scroll;
}
.tree-card {
  @apply min-w-500px;
}
.custom-tree-node {
  @apply flex-1 flex items-center justify-between text-sm pr-2;
}
</style>
